package com.phkj.qdh.utils.treela;


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by keranbin on 2016/8/30.
 */
public class TreeHelp {
    /**
     * 将服务器端取回的数据转化成Node
     * @param datas
     * @return
     * @throws IllegalAccessError
     */
    public static <T> List<Node> convertDataToNodes(List<T> datas) throws IllegalAccessException {
        List<Node> nodes = new ArrayList<>();
        Node node = null;
        for (T t : datas) {
            String id = "";
            String pid = "";
            String label = null;
            node = null;
            Class c = t.getClass();
            Field fields[] = c.getDeclaredFields();

            for (Field field : fields) {
                if (field.getAnnotation(TreeNodeId.class) != null) {
                    //设置访问权限，强制性的可以访问
                    field.setAccessible(true);
                    id= (String) field.get(t);
                }

                if (field.getAnnotation(TreeNodePid.class) != null) {
                    //设置访问权限，强制性的可以访问
                    field.setAccessible(true);
                    pid= (String) field.get(t);
                }

                if (field.getAnnotation(TreeNodeLabel.class) != null) {
                    //设置访问权限，强制性的可以访问
                    field.setAccessible(true);
                    label = (String) field.get(t);
                }


            }


            node = new Node(id, pid, label);
            nodes.add(node);
        }


        /**
         * 循环对比两个Node,设置节点间关联关系
         */
        for (int i = 0; i < nodes.size(); i++) {
            Node n = nodes.get(i);
            for (int j = i+1; j < nodes.size(); j++) {
                Node m = nodes.get(j);
                if (m.getId().equals( n.getPid())) {//m是n的父节点
                    m.getChildren().add(n);
                    n.setParent(m);
                } else if (m.getPid().equals( n.getId())) {//n是m的父节点
                    n.getChildren().add(m);
                    m.setParent(n);
                }
            }
        }

        /**
         * 设置节点的图标
         */
        for (Node n : nodes) {
            setNodeIcon(n);
        }
        return nodes;
    }

    /**
     * 为节点设置图标
     * 逻辑：（1）如果当前节点有孩子节点并且处于展开状态，那么设置向下的图标
     * （2）如果当前节点有孩子节点病区处于闭合状态，那么设置向右的图标
     * （3）如果当前节点没有孩子节点，传参-1，到时候判断是-1，不设置图标
     * @param n
     */
    private static void setNodeIcon(Node n) {
        if (n.getChildren().size() > 0 && n.isExpand()) {
          //  n.setIcon(R.mipmap.tree_ex);
        } else if (n.getChildren().size() > 0 && !n.isExpand()) {
            //n.setIcon(R.mipmap.tree_ec);
        } else {
            //n.setIcon(-1);
        }
    }

    /**
     * 得到排序后的Nodes
     * @param datas
     * @param <T>
     * @return
     */
    public static <T> List<Node> getSortedNodes(List<T> datas, int defaultExpandLevel) throws IllegalAccessException {
        List<Node> result = new ArrayList<>();
        List<Node> nodes = convertDataToNodes(datas);
        //获取树的根节点
        List<Node> rootNodes = getRootNodes(nodes);

        for (Node node : rootNodes) {
            addNode(result, node, defaultExpandLevel, 1);
        }
        return result;
    }

    /**
     * 从所有节点中过滤出根节点
     * @param nodes
     * @return
     */
    private static List<Node> getRootNodes(List<Node> nodes) {
        List<Node> root = new ArrayList<>();
        for (Node node : nodes) {
            if (node.isRoot()) {
                root.add(node);
            }
        }
        return root;
    }

    /**
     * 把一个节点的所有孩子节点都放入result
     * @param result
     * @param node               当前节点
     * @param defaultExpandLevel 默认初始化是展开几层
     * @param currentLevel       当前节点层级
     */
    private static void addNode(List<Node> result, Node node, int defaultExpandLevel, int currentLevel) {
        result.add(node);
        //如果默认展开层级大于或者当前节点层级，那么设置当前层级是展开的，否则设置是闭合的
        if (defaultExpandLevel >= currentLevel){
            node.setExpand(true);
        }

        //如果当前节点已经是叶子节点，那么不需要做任何处理啦
        if(node.isLeft()){
            return;

        }else{
            //如果当前节点不是叶子节点，递归循环遍历不断的添加子节点
            for(int i=0;i<node.getChildren().size();i++){
                addNode(result,node.getChildren().get(i),defaultExpandLevel,currentLevel+1);
            }
        }
    }

    /**
     * 过滤出可见的节点
     * @param nodes
     * @return
     */
    public static List<Node> filterVisibleNodes(List<Node> nodes){
        List<Node> visibleNodes=new ArrayList<>();
        for (Node node:nodes){
            //如果当前节点是根节点或者当前节点的父节点是展开的
            if (node.isRoot()||node.isParentExpand()){
                setNodeIcon(node);
                visibleNodes.add(node);
            }
        }
        return visibleNodes;
    }
}